# Appendix B. The echo Program

The following listing is echo.c :

>     #include <stdio.h>
>     #include <stdlib.h>
>     #define MAX_ENTRIES 10000
>     typedef struct
>         {
>         char *name;
>         char *val;
>         } entry;
>     char *makeword(char *line, char stop);
>     char *fmakeword(FILE *f, char stop, int *len);
>     char x2c(char *what);
>     void unescape_url(char *url);
>     void plustospace(char *str);
>     int main(int argc, char *argv[])
>         {
>         entry entries[MAX_ENTRIES];
>         register int x,m=0;
>         int cl;
>         char mbuf[200];
>         printf("Content-type: text/html\n\n");
>         if(strcmp(getenv("REQUEST_METHOD"),"POST"))
>             {
>             printf("This script should be referenced with a METHOD of POST.\n");
>             exit(1);
>             }
>         if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded"))
>             {
>             printf("This script can only be used to decode form results. \n");
>             exit(1);
>             }
>         cl = atoi(getenv("CONTENT_LENGTH"));
>     // Returns the length of data to come.
>         for(x=0;cl && (!feof(stdin));x++)
>             {
>             m=x;
>             entries[x].val = fmakeword(stdin,'&',&cl);
>             plustospace(entries[x].val);
>             unescape_url(entries[x].val);
>             entries[x].name = makeword(entries[x].val,'=');
>             }
>     //Reads in the data, breaking at the "&" symbols
>         printf("<H1>Query Results</H1>");
>     //Sends the top of the return HTML document.
>         printf("You submitted the following name/value pairs:<p>%c",10);
>         printf("<ul>%c",10);
>         for(x=0; x <= m; x++)
>             printf("<li> <code>%s = %s</code>%c",entries[x].name,
>                    entries[x].val,10);
>     //Lists the fields in the original form with the values filled in by
>     //the customer.
>         printf("</ul>%c",10);
>     }

This listing is the helper program echo2.c:

>     #include <stdio.h>
>     #define CR 13
>     #define LF 10
>     void getword(char *word, char *line, char stop) {
>         int x = 0,y;
>         for(x=0;((line[x]) && (line[x] != stop));x++)
>             word[x] = line[x];
>         word[x] = '\0'.
>         if(line[x]) ++x;
>         y=0;
>         while(line[y++] = line[x++]);
>     }
>     char *makeword(char *line, char stop) {
>         int x = 0,y;
>         char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
>         for(x=0;((line[x]) && (line[x] != stop));x++)
>             word[x] = line[x];
>         word[x] = '\0'.
>         if(line[x]) ++x;
>         y=0;
>         while(line[y++] = line[x++]);
>         return word;
>     }
>     char *fmakeword(FILE *f, char stop, int *cl) {
>         int wsize;
>         char *word;
>         int ll;
>         wsize = 102400;
>         ll=0;
>         word = (char *) malloc(sizeof(char) * (wsize + 1));
>         while(1) {
>             word[ll] = (char)fgetc(f);
>             if(ll==wsize) {
>                 word[ll+1] = '\0'.
>                 wsize+=102400;
>                 word = (char *)realloc(word,sizeof(char)*(wsize+1));
>             }
>             --(*cl);
>             if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
>                 if(word[ll] != stop) ll++;
>                 word[ll] = '\0'.
>                 return word;
>             }
>             ++ll;
>         }
>     }
>     char x2c(char *what) {
>         register char digit;
>         digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A'.+10 :
>                    (what[0] - '0'.);
>         digit *= 16;
>         digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A'.+10 :
>                    (what[1] - '0'.);
>         return(digit);
>     }
>     void unescape_url(char *url) {
>         register int x,y;
>         for(x=0,y=0;url[y];++x,++y) {
>             if((url[x] = url[y]) == '%'. {
>                 url[x] = x2c(&url[y+1]);
>                 y+=2;
>             }
>         }
>         url[x] = '\0'.
>     }
>     void plustospace(char *str) {
>         register int x;
>         for(x=0;str[x];x++) if(str[x] == '+'. str[x] = ' ';
>     }
>     int rind(char *s, char c) {
>         register int x;
>         for(x=strlen(s) - 1;x != -1; x--)
>             if(s[x] == c) return x;
>         return -1;
>     }
>     int getline(char *s, int n, FILE *f) {
>         register int i=0;
>         while(1) {
>             s[i] = (char)fgetc(f);
>             if(s[i] == CR)
>                 s[i] = fgetc(f);
>             if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
>                 s[i] = '\0'.
>                 return (feof(f) ? 1 : 0);
>             }
>             ++i;
>         }
>     }
>     void send_fd(FILE *f, FILE *fd)
>     {
>         int num_chars=0;
>         char c;
>         while (1) {
>             c = fgetc(f);
>             if(feof(f))
>                 return;
>             fputc(c,fd);
>         }
>     }
>     int ind(char *s, char c) {
>         register int x;
>         for(x=0;s[x];x++)
>             if(s[x] == c) return x;
>         return -1;
>     }
>     void escape_shell_cmd(char *cmd) {
>         register int x,y,l;
>         l=strlen(cmd);
>         for(x=0;cmd[x];x++) {
>             if(ind("&;'.q\"|*?~<>^()[]{}$\\",cmd[x]) != -1){
>                 for(y=l+1;y>x;y--)
>                     cmd[y] = cmd[y-1];
>                 l++; /* length has been increased */
>                 cmd[x] = '\\'.
>                 x++; /* skip the character */
>             }
>         }
>     }

Copyright © 2001 O'Reilly & Associates. All rights reserved.